package com.ycMc.Interceptor;


import com.alibaba.fastjson.JSON;
import com.ycMc.common.bean.Request;
import com.ycMc.common.bean.Response;
import com.ycMc.constant.CommonConstant;
import com.ycMc.utils.AESTools;
import com.ycMc.utils.JSONUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

public class DecryptInterceptor implements HandlerInterceptor {

    private static Logger logger = LoggerFactory.getLogger(DecryptInterceptor.class);

    @SuppressWarnings("rawtypes")
    private static Map<String, Class> requestDtoMap = new HashMap<String, Class>();

    public static <T> void register(String url, Class<T> cls) {
        requestDtoMap.put(url, cls);
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        response.setHeader("Access-Control-Allow-Origin", "*");
        request.setCharacterEncoding("utf-8");
        String param = request.getParameter(CommonConstant.REQUEST_PARAM);
        String contextPath = request.getContextPath();
        String requestUri = request.getRequestURI();
          Map<String,String[]> parameterMap = request.getParameterMap();
        Map<String,Object> nmap = new HashMap<String, Object>();
        for (String key : parameterMap.keySet()) {
            String[] temp = (String[])parameterMap.get(key);
            String temp1 = temp[0];
           String temp2 = new String ( temp1.getBytes("iso-8859-1"),"utf-8");
            nmap.put(key,temp2);

        }


        String temp = JSON.toJSONString(nmap);


        String locationPath = requestUri.replaceFirst(contextPath, "");
          Class<?> requestType = requestDtoMap.get(locationPath);



        // 获取参数Class类型
        if (requestType == null) {//requestType == null || param == null
            response.sendError(HttpStatus.NOT_ACCEPTABLE.value(), "The request is not supported");
            logger.error("{} with param {} is not supported", locationPath, temp);
            return false;
        }

        Request paramRequest = null;
        Response responseData = null;
        // 解密参数，并且转华为对应类型

        String method = request.getMethod();
        //get 方法直接获取参数对象即可。
      //  if(method.equals("GET")){
        try {
            paramRequest = (Request) AESTools.decrypt(temp, requestType);
        } catch (Exception e) {
            logger.error("{} with param {} is illegal", locationPath, temp);
            responseData = Response.build(Response.PARAM_PARSE_ERROR, CommonConstant.PARAM_PARSE_ERROR);
            response.setContentType("application/json; charset=utf-8");
            response.getWriter().write(JSONUtil.toJSONString(responseData));
            return false;
        }
    //}

        //post 方法 则需要封装成某一个对象
      //  else if (method.equals("POST")){}

        // 验证参数的基本合法性
        if(paramRequest!=null){
            responseData = paramRequest.validate(request);
            if (responseData != null) {
                logger.error("{} with param {} is invalid", locationPath, JSONUtil.toJSONString(paramRequest));
                response.setContentType("application/json; charset=utf-8");
                response.getWriter().write(JSONUtil.toJSONString(responseData));
                return false;
            }
        }

        // 把最终参数写到request的attribute中供controller使用
        request.setAttribute(CommonConstant.REQUEST_ATTRIBUTE, paramRequest);

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip) || "null".equalsIgnoreCase(ip))    {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)   || "null".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)    || "null".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        String uri = request.getRequestURI();
        String contextPath = request.getContextPath();
        String requestUri = request.getRequestURI();
        String locationPath = requestUri.replaceFirst(contextPath, "");
        String request_method = request.getMethod();
        Map<String,Object> nmap = new HashMap<String, Object>();

        String temp = JSON.toJSONString(nmap);

        logger.error("user_ip:{},request_uri:{},request_param:{},request_method:{}", ip, locationPath, temp, request_method);
    }
}
